package pl.wroc.uni.ii.puzzle.activity;

import java.util.Date;

import org.restlet.data.MediaType;
import org.restlet.representation.Representation;
import org.restlet.representation.StringRepresentation;
import org.restlet.resource.ClientResource;
import org.restlet.resource.ResourceException;

import pl.wroc.uni.ii.puzzle.R;
import pl.wroc.uni.ii.puzzle.data.DateAdapter;
import pl.wroc.uni.ii.puzzle.data.Score;
import pl.wroc.uni.ii.puzzle.game.Game;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.facebook.android.DialogError;
import com.facebook.android.Facebook;
import com.facebook.android.FacebookError;
import com.facebook.android.Facebook.DialogListener;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class PublishScoreActivity extends Activity {

	private static final String API_ID = "293113600725466";
	private static final String[] PERMISSIONS = new String[] {"publish_stream"};
	private static final String TOKEN = "access_token";
	private static final String EXPIRES = "expires_in";
	private static final String KEY = "facebook-credentials";

	private String scoreString;
	private Score score;
	private Facebook facebook;

	@Override
	public void onCreate(Bundle icicle) {
		super.onCreate(icicle);
		setContentView(R.layout.publish_score);

		initLayout();

		facebook = new Facebook(API_ID);
		restoreCredentials(facebook);
	}

	private void initLayout() {
		score = (Score) getIntent().getExtras().get("score");
		scoreString = String.valueOf(score);
		TextView scoreView = (TextView) findViewById(R.id.scoreTextView);
		scoreView.setText(scoreString);

		Button shareButton = (Button) findViewById(R.id.shareButton);
		shareButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				publishScore();
			}
		});

		Button sendToServerButton = (Button) findViewById(R.id.sendToServerButton);
		sendToServerButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				sendScoreToServer();
			}
		});

		Button cancelButton = (Button) findViewById(R.id.backButton);
		cancelButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				PublishScoreActivity.this.finish();
			}
		});
	}

	public boolean saveCredentials(Facebook facebook) {
		Editor editor = getApplicationContext().getSharedPreferences(KEY,Context.MODE_PRIVATE).edit();
		editor.putString(TOKEN, facebook.getAccessToken());
		editor.putLong(EXPIRES, facebook.getAccessExpires());
		return editor.commit();
	}

	public boolean restoreCredentials(Facebook facebook) {
		SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences(KEY, Context.MODE_PRIVATE);
		facebook.setAccessToken(sharedPreferences.getString(TOKEN, null));
		facebook.setAccessExpires(sharedPreferences.getLong(EXPIRES, 0));
		return facebook.isSessionValid();
	}

	private void publishScore() {
		if (!facebook.isSessionValid()) {

			facebook.authorize(this, PERMISSIONS, new DialogListener() {
				@Override
				public void onComplete(Bundle values) {
					saveCredentials(facebook);
					if (scoreString != null) {
						postToWall("Score: " + scoreString);
					}
				}

				@Override
				public void onFacebookError(FacebookError e) {
					Log.w(PublishScoreActivity.class.getName(), "Authentication with Facebook failed", e);
					showToast(getString(R.string.authenticationWithFacebookFailed));
				}

				@Override
				public void onError(DialogError e) {
					Log.w(PublishScoreActivity.class.getName(), "Authentication with Facebook failed", e);
					showToast(getString(R.string.authenticationWithFacebookFailed));
				}

				@Override
				public void onCancel() {
					showToast(getString(R.string.authenticationWithFacebookCanceled));
				}
			});
		} else {
			if (scoreString != null) {
				postToWall("Score: " + scoreString);
			}
		}
	}
	
	private void sendScoreToServer() {
		try {
			GsonBuilder gsonb = new GsonBuilder();
			gsonb.registerTypeAdapter(Date.class, new DateAdapter());
			Gson gson = gsonb.create();
			ClientResource cr = new ClientResource(Game.PUZZLE_WS_ADDRESS);
			String scoreString = gson.toJson(score);
			Representation rep = new StringRepresentation(scoreString, MediaType.APPLICATION_JSON);
			cr.put(rep);
			showToast(getString(R.string.scoreSentToServer));
		} catch (ResourceException e) {
			Log.w(PublishScoreActivity.class.getName(), "Sending score to server failed", e);
			showToast(getString(R.string.sendigScoreToServerFailed));
		}
	}

	private void postToWall(String message) {
		Bundle parameters = new Bundle();
		parameters.putString("message", message);
		parameters.putString("description", "topic share");
		try {
			facebook.request("me");
			String response = facebook.request("me/feed", parameters, "POST");
			Log.d("Tests", "got response: " + response);
			if (response == null || response.equals("")	|| response.equals("false")) {
				showToast(getString(R.string.blankResponse));
			} else {
				showToast(getString(R.string.messagePostedToYourFacebookWall));
			}
		} catch (Exception e) {
			Log.w(PublishScoreActivity.class.getName(), "Failed to post to wall", e);
			showToast(getString(R.string.failedToPostToWall));
		}
	}

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		facebook.authorizeCallback(requestCode, resultCode, data);
	}

	private void showToast(String message) {
		Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
	}

}